// Source code is decompiled from a .class file using FernFlower decompiler.
package org.springframework.security.config.annotation.web.builders;

import java.io.Serializable;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter;
import org.springframework.security.web.authentication.switchuser.SwitchUserFilter;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.header.HeaderWriterFilter;
import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
import org.springframework.security.web.savedrequest.RequestCacheAwareFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.web.filter.CorsFilter;

final class FilterComparator implements Comparator<Filter>, Serializable {
   private static final int INITIAL_ORDER = 100;
   private static final int ORDER_STEP = 100;
   private final Map<String, Integer> filterToOrder = new HashMap();

   FilterComparator() {
      Step order = new Step(100, 100);
      this.put(ChannelProcessingFilter.class, order.next());
      this.put(ConcurrentSessionFilter.class, order.next());
      this.put(WebAsyncManagerIntegrationFilter.class, order.next());
      this.put(SecurityContextPersistenceFilter.class, order.next());
      this.put(HeaderWriterFilter.class, order.next());
      this.put(CorsFilter.class, order.next());
      this.put(CsrfFilter.class, order.next());
      this.put(LogoutFilter.class, order.next());
      this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter", order.next());
      this.filterToOrder.put("org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter", order.next());
      this.put(X509AuthenticationFilter.class, order.next());
      this.put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
      this.filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter", order.next());
      this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter", order.next());
      this.filterToOrder.put("org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter", order.next());
      this.put(UsernamePasswordAuthenticationFilter.class, order.next());
      this.put(ConcurrentSessionFilter.class, order.next());
      this.filterToOrder.put("org.springframework.security.openid.OpenIDAuthenticationFilter", order.next());
      this.put(DefaultLoginPageGeneratingFilter.class, order.next());
      this.put(DefaultLogoutPageGeneratingFilter.class, order.next());
      this.put(ConcurrentSessionFilter.class, order.next());
      this.put(DigestAuthenticationFilter.class, order.next());
      this.filterToOrder.put("org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter", order.next());
      this.put(BasicAuthenticationFilter.class, order.next());
      this.put(RequestCacheAwareFilter.class, order.next());
      this.put(SecurityContextHolderAwareRequestFilter.class, order.next());
      this.put(JaasApiIntegrationFilter.class, order.next());
      this.put(RememberMeAuthenticationFilter.class, order.next());
      this.put(AnonymousAuthenticationFilter.class, order.next());
      this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter", order.next());
      this.put(SessionManagementFilter.class, order.next());
      this.put(ExceptionTranslationFilter.class, order.next());
      this.put(FilterSecurityInterceptor.class, order.next());
      this.put(SwitchUserFilter.class, order.next());
   }

   public int compare(Filter lhs, Filter rhs) {
      Integer left = this.getOrder(lhs.getClass());
      Integer right = this.getOrder(rhs.getClass());
      return left - right;
   }

   public boolean isRegistered(Class<? extends Filter> filter) {
      return this.getOrder(filter) != null;
   }

   public void registerAfter(Class<? extends Filter> filter, Class<? extends Filter> afterFilter) {
      Integer position = this.getOrder(afterFilter);
      if (position == null) {
         throw new IllegalArgumentException("Cannot register after unregistered Filter " + afterFilter);
      } else {
         this.put(filter, position + 1);
      }
   }

   public void registerAt(Class<? extends Filter> filter, Class<? extends Filter> atFilter) {
      Integer position = this.getOrder(atFilter);
      if (position == null) {
         throw new IllegalArgumentException("Cannot register after unregistered Filter " + atFilter);
      } else {
         this.put(filter, position);
      }
   }

   public void registerBefore(Class<? extends Filter> filter, Class<? extends Filter> beforeFilter) {
      Integer position = this.getOrder(beforeFilter);
      if (position == null) {
         throw new IllegalArgumentException("Cannot register after unregistered Filter " + beforeFilter);
      } else {
         this.put(filter, position - 1);
      }
   }

   private void put(Class<? extends Filter> filter, int position) {
      String className = filter.getName();
      this.filterToOrder.put(className, position);
   }

   private Integer getOrder(Class<?> clazz) {
      while(clazz != null) {
         Integer result = (Integer)this.filterToOrder.get(clazz.getName());
         if (result != null) {
            return result;
         }

         clazz = clazz.getSuperclass();
      }

      return null;
   }
}
